package sysinfo

import (
	"encoding/json"
	"github.com/go-kit/log/level"
	"github.com/prometheus/common/promlog"
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/disk"
	"github.com/shirou/gopsutil/v3/host"
	"github.com/shirou/gopsutil/v3/mem"
	"github.com/shirou/gopsutil/v3/net"
)

type SysInfo struct {
	Host      *host.InfoStat         `json:"host"`
	CPU       []cpu.InfoStat         `json:"cpu"`
	Memory    *mem.VirtualMemoryStat `json:"memory"`
	Disk      []disk.UsageStat       `json:"disk"`
	Interface net.InterfaceStatList  `json:"interface"`
}

var logger = promlog.New(&promlog.Config{})

func init() {

}

func (si *SysInfo) SysInfo() {
	si.hostInfo()
	si.memoryInfo()
	si.cpuInfo()
	si.diskInfo()
	si.interfaceInfo()
}

func (si SysInfo) String() string {
	s, _ := json.Marshal(si)
	return string(s)
}

//获取操作系统信息
func (si *SysInfo) hostInfo() {
	info, err := host.Info()
	if err != nil {
		level.Error(logger).Log("err", err)
	}
	si.Host = info
	level.Info(logger).Log("msg", "pull host info success")
}

//获取内存信息
func (si *SysInfo) memoryInfo() {
	info, err := mem.VirtualMemory()
	if err != nil {
		level.Error(logger).Log("err", err)
	}
	si.Memory = info
	level.Info(logger).Log("msg", "pull memory info success")
}

//获取CPU信息
func (si *SysInfo) cpuInfo() {
	info, err := cpu.Info()
	if err != nil {
		level.Error(logger).Log("err", err)
	}
	si.CPU = info
	level.Info(logger).Log("msg", "pull cpu info success")
}

//获取硬盘信息
func (si *SysInfo) diskInfo() {
	infos, err := disk.Partitions(false)
	if err != nil {
		level.Error(logger).Log("err", err)
	}
	usageStatSlice := make([]disk.UsageStat, 0, 8)
	for _, info := range infos {
		mountPoint := info.Mountpoint
		device := info.Device
		usageStat, _ := disk.Usage(mountPoint)
		usageStat.Path = device
		usageStatSlice = append(usageStatSlice, *usageStat)
	}
	si.Disk = usageStatSlice
	level.Info(logger).Log("msg", "pull disk info success")
}

//获取网口信息
func (si *SysInfo) interfaceInfo() {
	info, err := net.Interfaces()
	if err != nil {
		level.Error(logger).Log("err", err)
	}
	si.Interface = info
	level.Info(logger).Log("msg", "pull interface info success")
}
